package test
{
	import algorithm.DijkstraForMap;
	import algorithm.DijkstraVertex;
	import algorithm.IPassable;
	
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.utils.Dictionary;
	
	import org.musince.util.DictionaryUtilPlus;
	
	[SWF(width="800", height="800")]
	
	public class DijkstraTest extends Sprite implements IPassable
	{
		private var _colNum:int;
		private var _rowNum:int;
		private var _gridWidth:int;
		public var dijkstra:DijkstraForMap;
		
		private var _blocks:Vector.< Vector.<Boolean> >;
		private var _range:Dictionary = new Dictionary;
		private var _fromX:int = -1;
		private var _fromY:int = -1;
		
		public function DijkstraTest()
		{
			super();
			_gridWidth = 50;
			_colNum = stage.stageWidth/_gridWidth;
			_rowNum = stage.stageHeight/_gridWidth;
			dijkstra = new DijkstraForMap(this, _colNum, _rowNum);

			_blocks = new Vector.< Vector.<Boolean> >(_colNum);
			for (var i:int = 0; i < _colNum; i++) {
				_blocks[i] = new Vector.<Boolean>(_rowNum);
			}
			stage.addEventListener(MouseEvent.CLICK, onMouseDown);
			stage.addEventListener(MouseEvent.RIGHT_MOUSE_DOWN, onRightMouseDown);
			rendering();
		}
		
		private function onMouseDown(e:MouseEvent):void {
			_fromX = e.localX / _gridWidth;
			_fromY = e.localY / _gridWidth;
			trace("click x:" + _fromX + " y:" + _fromY);
			_range = dijkstra.solve(_fromX, _fromY, 5);
			trace(DictionaryUtilPlus.size(_range));
			rendering();			
		}
		
		public function passable(x:int, y:int):Boolean {
			if (x < 0) return false;
			if (y < 0) return false;
			if (x >= _colNum) return false;
			if (y >= _rowNum) return false;
			return !_blocks[x][y];
		}
		
		private function onRightMouseDown(e:MouseEvent):void {
			var x:int = e.localX / _gridWidth;
			var y:int = e.localY / _gridWidth;
			trace("block x:" + x + " y:" + y);
			_blocks[x][y] = !_blocks[x][y];
			rendering();
		}
		
		public function rendering():void {
			var g:Graphics = this.graphics;
			var x:int = _gridWidth * _colNum;
			var y:int;
			var i:int;var j:int;
			g.clear();
			g.lineStyle(1);
			for (i = 1; i < _rowNum; i++) {
				y = _gridWidth * i;
				g.moveTo(0, y);
				g.lineTo(x, y);
			}
			y = _gridWidth * _rowNum;
			for (j = 1; j < _colNum; j++) {
				x = _gridWidth * j;
				g.moveTo(x, 0);
				g.lineTo(x, y);
			}
			g.beginFill(0xFF0000);
			for (i = 0; i < _colNum; i++) {
				for (j = 0; j < _rowNum; j++) {
					if (_blocks[i][j]) {
						g.drawRect(i*_gridWidth, j*_gridWidth, _gridWidth, _gridWidth); 
					}
				}
			}
			g.endFill();
			
			g.beginFill(0x00FF00, 0.6);
			for each (var node:DijkstraVertex in _range) {
				g.drawRect(node.x *_gridWidth, node.y *_gridWidth, _gridWidth, _gridWidth); 
			}
			g.endFill();
			
			g.lineStyle(4, 0x0000FF);
			var it:DijkstraVertex;
			for each (node in _range) {
				it = node;
				g.moveTo(centerX(node), centerY(node));
				while (it.pre != null) {
					g.lineTo(centerX(node.pre), centerY(node.pre));
					it = it.pre;
				}
			}
			
			g.beginFill(0xFFFF00, 0.6);
			g.drawCircle(_fromX *_gridWidth + _gridWidth/2, _fromY *_gridWidth + _gridWidth/2, 10); 
			g.endFill();
		}
		
		public function centerX(node:DijkstraVertex):int {
			return node.x *_gridWidth+_gridWidth/2;
		}
		
		public function centerY(node:DijkstraVertex):int {
			return node.y *_gridWidth+_gridWidth/2;
		}
		
	}
}